// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.jasmin.unit.memory;

import com.dustedpixels.jasmin.unit.Unit;
import com.dustedpixels.jasmin.unit.tools.Oscilloscope;
import com.dustedpixels.jasmin.unit.tools.Pin;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class ROM implements Unit {
  // (output) address bus
  public int ADDR;

  // (input) read request
  public boolean RD;

  // (output, tristate) data bus
  public int DATA;
  public int DATA_Z = 0;

  private final int addressMask;
  private final int[] dataArray;

  public ROM(int addressBits, int[] dataArray) {
    this.addressMask = (1 << addressBits) - 1;
    this.dataArray = dataArray;
  }

  public void updateEndPoints() {
    if (RD) {
      DATA = dataArray[ADDR & addressMask];
      DATA_Z = ~0;
    } else {
      DATA_Z = 0;
    }
  }

  public static void main(String[] args) {
    int bits = 10;
    ROM rom = new ROM(bits, new int[1 << bits]);

    Oscilloscope oscilloscope = new Oscilloscope(Pin.of("ADDR", rom, "ADDR"), Pin.of("DATA", rom,
        "DATA"), Pin.of("RD", rom, "RD"));

    // Cycle 1: Put address
    rom.ADDR = 12;
    rom.updateEndPoints();
    oscilloscope.sample();

    // Cycle 2: Put RD request
    rom.RD = true;
    rom.updateEndPoints();
    oscilloscope.sample();

    // Cycle 3: Read data, and release RD
    rom.RD = false;
    rom.updateEndPoints();
    oscilloscope.sample();

    oscilloscope.print(3);
  }
}
